/**
 * 局部变量具有块作用域
 *   局部变量具有块作用域，这意味着它们的作用域是从定义点到定义块的末尾。
 * 
 * 局部变量有自动存储期限
 *   变量的存储持续时间（通常称为持续时间）决定了控制变量创建和销毁的时间和方式的规则。在大多数情况下，变量的存储持续时间直接决定其lifetime。
 * 
 * 局部变量没有链接
 *   标识符还有另一个名为 的属性linkage。标识符的链接确定该名称的其他声明是否引用同一对象。
 *   局部变量有no linkage，这意味着每个声明都引用一个唯一的对象。
 * 
 * 
 * 
 * 声明全局变量
 *   按照惯例，全局变量在全局命名空间中的文件顶部、包含项下方声明。
 * 
 * 在全局命名空间中声明的标识符具有全局命名空间范围（通常称为全局范围，有时非正式地称为文件范围），这意味着它们从声明点到声明它们的文件末尾都是可见的。
 * 一旦声明，全局变量就可以在文件中的任何位置使用！
 * 
 * 关键见解
 *   命名空间内声明的变量也是全局变量。
 * 
 * 全局变量具有静态持续时间
 *   全局变量在程序启动时创建，在程序结束时销毁。这称为静态持续时间。具有静态持续时间的变量有时称为静态变量。
 * 
 * 全局变量初始化
 *   与默认情况下未初始化的局部变量不同，具有静态持续时间的变量默认为零初始化。
 * 
 * 全局变量的动态初始化在 C++ 中会导致很多问题。尽可能避免动态初始化。
 *   例如：给定两个文件a.cpp和b.cpp，其中任何一个都可以首先初始化其全局变量。这意味着，如果a.cpp中的变量依赖于b.cpp中的值，则这些变量有 50% 的可能性尚未初始化。
 * 
 */

#include <iostream>

// Variables declared outside of a function are global variables
int g_x {}; // global variable g_x

char* test1 = "hello";
int test2;

// Non-constant global variables
int g_x1;                 // defines non-initialized global variable (zero initialized by default)
int g_x2 {};              // defines explicitly value-initialized global variable
int g_x3 { 1 };           // defines explicitly initialized global variable

// Const global variables
// const int g_y1;           // error: const variables must be initialized
const int g_y2 { 2 };     // defines initialized global const

// Constexpr global variables
// constexpr int g_y3;       // error: constexpr variables must be initialized
constexpr int g_y4 { 3 }; // defines initialized global constexpr

int main()
{
    std::cout << "Enter an integer: ";
    int smaller{};
    std::cin >> smaller;

    std::cout << "Enter a larger integer: ";
    int larger{};
    std::cin >> larger;

    // if user did it wrong
    if (smaller > larger)
    {
        // swap values of smaller and larger
        std::cout << "Swapping the values\n";

        int temp{ larger };
        larger = smaller;
        smaller = temp;
    } // temp dies here

    std::cout << "The smaller value is: " << smaller << '\n';
    std::cout << "The larger value is: " << larger << '\n';



    int test3;
    std::cout << test1 << "\n";
    std::cout << test2 << "\n";
    std::cout << test3 << "\n";

    return 0;
} // smaller and larger die here